using System;
using System.Collections.Generic;
using System.Windows.Forms;
using OhioState.Graphics;

namespace OhioState.Controls
{
	/// <summary>
	/// Summary description for ExaminerMouseHandler.
	/// </summary>
	/// 
	public class TransformMouseController
    {
        #region Private members
        private System.Windows.Forms.Control _ownerControl;
        protected CameraControl transformCtrl = new CameraControl();
        protected bool NowInteracting = false;
        protected MouseEventHandler m_MouseMoveDelegate;
        protected MouseEventHandler m_MouseUpDelegate;
        protected IList<ITransform> slaveList = new List<ITransform>();
        protected IList<IZoomLens> slaveZoomList = new List<IZoomLens>();
        #endregion

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="targetControl">The control to which we should subscribe our
        /// mouse events.</param>
        /// <param name="setKeyboardFocusOnMouseDown">A Boolean indicating whether
        /// the control should recieve the keyboard focus (true) when the mouse is
        /// clicked (mouse-down) within the control. This is needed if the user wishes
        /// to control the entities(slaves) with keyboard keys.</param>
        public TransformMouseController()
		{
			//
			// The cameraCtrl controls need to be attached to the mouse handler's, but we will delay
			//    that until after a mouse down. The Examiner functions below determine what to 
			//    attach on a mouse down event. We will create two separate functions and attach
			//    one to each panel.
			//
		}
        /// <summary>
        /// Get or set the control whose mouse events affect this controller.
        /// </summary>
        public System.Windows.Forms.Control OwnerControl
        {
            get { return _ownerControl; }
            set
            {
                SetOwnerControl(value);
            }
        }

        protected virtual void SetOwnerControl( Control control )
        {
            _ownerControl = control;
        }
        /// <summary>
        /// Add a slave to the list of slaves that this controller controls.
        /// </summary>
        /// <param name="slave">The slave to be controlled.</param>
        public void AddSlave(ITransform slave)
        {
            transformCtrl.rotate += new OhioState.Controls.CameraControl.Rotate(slave.Rotate);
            transformCtrl.pan += new OhioState.Controls.CameraControl.Pan(slave.Translate);
            //_cameraCtrl.zoom += new OhioState.Controls.CameraControl.Zoom(camera.ZoomLens);
            slaveList.Add(slave);
        }
        public void AddSlave(IZoomLens slave)
        {
            transformCtrl.zoom += new OhioState.Controls.CameraControl.Zoom(slave.ZoomLens);
            slaveZoomList.Add(slave);
        }
        /// <summary>
        /// Remove a slave from the control list.
        /// </summary>
        /// <param name="slave">The slave to be removed.</param>
        public void RemoveSlave(ITransform slave)
        {
            if (slaveList.Contains(slave))
            {
                transformCtrl.rotate -= new OhioState.Controls.CameraControl.Rotate(slave.Rotate);
                transformCtrl.pan -= new OhioState.Controls.CameraControl.Pan(slave.Translate);
                //_cameraCtrl.zoom -= new OhioState.Controls.CameraControl.Zoom(camera.ZoomLens);
                slaveList.Remove(slave);
            }
            else
            {
                throw new ArgumentException("Can not remove object. The specified ITransform is not attached to the ExaminerMouseHandler.");

            }
        }

        /// <summary>
        /// Remove a slave from the control list.
        /// </summary>
        /// <param name="slave">The slave to be removed.</param>
        public void RemoveSlave(IZoomLens slave)
        {
            if (slaveZoomList.Contains(slave))
            {
                transformCtrl.zoom -= new OhioState.Controls.CameraControl.Zoom(slave.ZoomLens);
                slaveZoomList.Remove(slave);
            }
            else
            {
                throw new ArgumentException("Can not remove object. The specified ITransform is not attached to the ExaminerMouseHandler.");

            }
        }

        #region Mouse Callbacks
		protected void My_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) 
		{
            System.Windows.Forms.Control currentCtrl = (System.Windows.Forms.Control)sender;
			//
			// Release the Mouse.
			//
			currentCtrl.Capture = false;
			//
			// Reset the cursor.
			//
			currentCtrl.Cursor = Cursors.Default;
			//
			// Turn-off any movement interactions with the mouse-move.
			//   - For accessibility, we might want sticky keys for this.
			//
			// Disconnect the MouseEventHandler
			//
			currentCtrl.MouseMove -= m_MouseMoveDelegate;
			currentCtrl.MouseUp -= m_MouseUpDelegate;

			EndManipulation();
		}
		protected void BeginManipulation()
		{
			NowInteracting = true;
			// Loop thru the list of slaves and notify them of upcoming changes.
            foreach (ITransform slave in slaveList)
            {
                slave.BeginManipulation();
            }
            foreach (IZoomLens slave in slaveZoomList)
            {
                slave.BeginManipulation();
            }
        }
		protected void EndManipulation()
		{
			NowInteracting = false;
			// Loop thru the list of slaves and notify them that changes are over.
			foreach( ITransform slave in slaveList )
			{
				slave.EndManipulation();
			}
            foreach (IZoomLens slave in slaveZoomList)
            {
                slave.EndManipulation();
            }
        }
		#endregion Mouse Callbacks
	}
}
